<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVertexShader" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    attribute vec2 a_Pin;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    varying vec2 v_Pin;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        v_Pin = a_Pin;
    }
</script>
<!-- rgb化 -->
<script id="ColorFragmentShader" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    uniform float u_Set;
    varying vec2 v_Pin;
    void main(){
        float set = u_Set / 80.0;
        vec4 r = texture2D(u_Sampler, v_Pin - set);
        vec4 g = texture2D(u_Sampler, v_Pin);
        vec4 b = texture2D(u_Sampler, v_Pin + set);
        
        gl_FragColor = vec4(r.r, g.g, b.b, 1.0);
    }
</script>
<!-- 像素化 -->
<script id="ColorFragmentShader1" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    uniform float u_Set;
    varying vec2 v_Pin;
    void main(){
        float set = 50.0;
        vec2 uv = v_Pin;
        uv.x *= set;
        uv.y *= set;
        uv.x = floor(uv.x);
        uv.y = floor(uv.y);
        uv.x /= set;
        uv.y /= set;
        
        gl_FragColor = texture2D(u_Sampler, uv);
    }
</script>
<!-- 扭曲化 -->
<script id="ColorFragmentShader2" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    uniform sampler2D u_Texture;
    uniform float u_Set;
    varying vec2 v_Pin;
    void main(){
        float set = smoothstep(0.0, 1.0, (u_Set + 1.0) / 2.0) * 0.04;
        vec2 disp = texture2D(u_Texture, v_Pin).xy;
        disp = ((disp * 2.0) - 1.0) * set; //把[0 - 1]变成[-1 - 1]
        gl_FragColor = texture2D(u_Sampler, v_Pin + disp);
    }
</script>
<!-- 热浪化(无效果) -->
<script id="ColorFragmentShader3" type="x-shader/x-fragment">
    precision mediump float;
    uniform sampler2D u_Sampler;
    uniform sampler2D u_Texture;
    uniform float u_Set;
    varying vec2 v_Pin;
    void main(){
        float rl = 0.0001;
        float set = (u_Set + 1.0) / 2.0;

        vec2 textureUv = vec2(v_Pin.x + set, v_Pin.y + set);
        vec2 disp = texture2D(u_Texture, textureUv).xy;

        disp = ((disp * 2.0) - 1.0) * rl; //把[0 - 1]变成[-1 - 1]
        gl_FragColor = texture2D(u_Sampler, v_Pin + disp);
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'
    import Square from '../js/objs/Square.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl", { antialias: true, });

    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    gl.enable(gl.DEPTH_TEST);
    //#endregion

    const scene = new Scene({ gl: gl });
    scene.addAxisProgram();
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVertexShader').innerText,
            document.querySelector('#ColorFragmentShader1').innerText),
        attribs: ['a_Position', 'a_Pin'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_Sampler', 'u_Set', 'u_Texture']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const eye = new Vector3(0, 0, 2);
    const lookAt = new Vector3();

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4,
        eye,
        lookAt,
    });


    const axis = new Obj3D().createAxis('axis');
    // scene.add(axis);

    const [w, h] = [0.24, 0.2];
    const vectices = [
        -w, h, 0,
        -w, -h, 0,
        w, -h, 0,
        w, h, 0,
    ];


    const image = new Image();
    image.src = '../Image/Image01.jpg';
    const texture = new Image();
    texture.src = '../Image/Displacements.png';


    Promise.all([
        imgPromise(image),
        imgPromise(texture),
    ]).then(() => {

        let obj01 = new Obj3D({
            geo: new Geo({
                data: {
                    'a_Position': { size: 3, array: new Float32Array(vectices) },
                    'a_Pin': { size: 2, array: new Float32Array([0, 1, 0, 0, 1, 0, 1, 1]) },
                },
                element: {
                    array: new Uint16Array([0, 1, 2, 0, 2, 3])
                }
            }),
            mat: new Mat({
                program: 'color',
                mode: ['TRIANGLES'],
                data: {
                    'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                    'u_ModelM4': { type: 'uniformMatrix4fv', value: modelM4.elements },
                    'u_Set': { type: 'uniform1f', value: 0 },
                },
                maps: {
                    'u_Sampler': {
                        image: image,
                        WRAP_W: gl.CLAMP_TO_EDGE,
                        WRAP_H: gl.CLAMP_TO_EDGE,
                        MIN_FILTER: gl.LINEAR,
                    },
                    'u_Texture': {
                        image: texture,
                        WRAP_W: gl.CLAMP_TO_EDGE,
                        WRAP_H: gl.CLAMP_TO_EDGE,
                        MIN_FILTER: gl.LINEAR,
                    },
                }
            }),
        });
        scene.add(obj01);
    });


    //修改图片
    function updateImage(images) {
        poly.texture['u_Texture1'] = {
            image: images[0],
            WRAP_W: gl.CLAMP_TO_EDGE,
            WRAP_H: gl.CLAMP_TO_EDGE,
        };
        poly.texture['u_Texture2'] = {
            image: images[1],
            WRAP_W: gl.CLAMP_TO_EDGE,
            WRAP_H: gl.CLAMP_TO_EDGE,
        };

        poly.updateTexture();
    }



    let set = 0;
    (function ani(time) {
        set = Math.sin(time / 200);
        scene.setUniform('u_Set', { value: set });

        draw();
        requestAnimationFrame(ani)
    })(0);


    function draw() {
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }
</script>

</html>